home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
WSNAKE.ZIP
/
SNAKE
/
SNAKE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-29
|
8KB
|
402 lines
// the Snake
// Copyright (c)1996 Fredrik Wangel (WaF)
//
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include "snake.h"
void waitretrace(void);
void waitdisplay(void);
int keyhit(void);
void flushkbd(void);
void setborderc(byte color);
void show_display(void);
void hide_display(void);
void draw_score(void);
void fade_to_black(byte start, byte stop, byte steps);
void fade_to_color(byte start, byte stop, byte steps);
#define TRUE '-'/'-'
#define FALSE '-'-'-'
#define KEY_SOUND 'S'
#define KEY_ESC 27
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define SCRSX 80
#define XSIZE 80
#define YSIZE 40
#define BLOCKS 20
#define LX2POS 44
#define LXPOS 1
#define LYPOS YSIZE + 2
#define GP ((YSIZE * BLOCKS) / XSIZE) // Base points
#define ADDSNAKE 15 // random(x) at increase
#define LOOSESNAKE 4 // and decrease respectively
#define BEGINSNAKE 2 // starting length of the snake
#define FROGAMOUNT 5 // number of frogs
#define HI(a) (a & 0xff00) / 0x100
#define LO(a) (a & 0x00ff)
#define FOREVER for(;;)
byte key, firsttime = 1, ljud = 1;
byte grid[XSIZE][YSIZE];
byte frx[FROGAMOUNT], fry[FROGAMOUNT];
int snx[1500], sny[1500];
int length, head, tail;
int grow, decline, frogtime[FROGAMOUNT];
int millifemtio, tid;
long score;
long bestscore = 0;
int besttid = 0, bestlength = 0;
const word Clear = 0x2000 + byte(' ');
const word Frog = 0x2A00 + byte('Ω');
const word Snake = 0x2C00 + byte('@');
const word Brick = 0x2600 + byte('≡');
const word Block = 0x2F00 + byte('█');
void save_palette()
{
for(word i = 0; i < 64; i++)
getpalrgb(i, pal_orig[i].r, pal_orig[i].g, pal_orig[i].b);
}
void restore_palette()
{
for(word i = 0; i < 64; i++)
setpalrgb(i, pal_orig[i].r, pal_orig[i].g, pal_orig[i].b);
}
void clear_palette()
{
for(word i = 0; i < 64; i++)
{
pal[i].r = 0;
pal[i].g = 0;
pal[i].b = 0;
setpalrgb(i, 0, 0, 0);
}
}
void waitforkey(void)
{
gotoxy(LXPOS, LYPOS + 2);
printf("** Press any key to begin **");
clreol();
printf("\r");
flushkbd();
while(!keyhit());
clreol();
}
void notify(void)
{
if(ljud)
{
buzz(2500); delay(25);
buzz(1500); delay(25); buzz(750); delay(50);
buzz(1000); delay(100); quiet();
}
draw_score();
gotoxy(LXPOS, LYPOS + 1);
printf("You played for %04d sec.", tid);
clreol();
delay(500);
}
void put_block(word x, word y, word item)
{
asm {
mov ax, 0xb800
mov es, ax
mov ax, y
mov dl, SCRSX
shl dl, 1
mul dl
mov dx, x
shl dx, 1
add ax, dx
mov di, ax
mov ax, item
mov [es:di], ax
}
}
void set_point(word x, word y, word item)
{
put_block(x, y, item);
grid[x][y] = HI(item);
}
void clear_grid(void)
{
word x, y;
hide_display();
for(x=0; x < XSIZE; x++)
{
for(y=0; y < YSIZE; y++)
if(grid[x][y] != HI(Clear))
set_point(x, y, Clear);
set_point(x, YSIZE - 1, Block);
set_point(x, 0, Block);
}
for(y=0; y < YSIZE; y++)
{
set_point(XSIZE - 1, y, Block);
set_point(0, y, Block);
}
for(x=0; x < BLOCKS; x++)
set_point(random(XSIZE - 1) + 1, random(YSIZE - 1) + 1, Block);
show_display();
}
void draw_score(void)
{
gotoxy(LXPOS, LYPOS);
printf("Length: %04d Points: %010ld\r", length, score);
if((score > bestscore) || (length > bestlength))
{
if(score > bestscore)
bestscore = score;
else
bestlength = length;
gotoxy(LX2POS, LYPOS);
printf("Longest: %04d Highscore: %010ld\r", bestlength, bestscore);
// printf("Longest: %04d Highscore: %010ld\r", bestlength, bestscore);
}
}
void create_frog(int n)
{
word x, y;
do
{
x = random(XSIZE - 1) + 1;
y = random(YSIZE - 1) + 1;
}
while (grid[x][y] != HI(Clear));
frx[n] = x;
fry[n] = y;
set_point(x, y, Frog);
frogtime[n] = 20 + random(50);
if(ljud)
{
buzz(50); delay(5); quiet();
}
}
void check_frogs(void)
{
word n, x, y;
for(n=0; n < FROGAMOUNT; n++)
if(!frogtime[n]--)
{
x = frx[n];
y = fry[n];
create_frog(n);
set_point(x, y, random(10)?Clear:Brick);
}
}
void replace_frog(word x, word y)
{
word n;
for(n=0; n < FROGAMOUNT; n++)
if(frx[n] == x && fry[n] == y)
create_frog(n);
set_point(x, y, Clear);
}
void setup_game(void)
{
clear_grid();
score = 0;
millifemtio = 0;
tid = 0;
length = 1;
grow = BEGINSNAKE - 1;
decline = 0;
head = tail = 0;
snx[0] = XSIZE / 2;
sny[0] = YSIZE / 2;
set_point(snx[0], sny[0], Snake);
key = KEY_RIGHT;
for(word i=0; i < FROGAMOUNT; i++)
create_frog(i);
if(firsttime)
{
firsttime = 0;
fade_to_color();
}
waitforkey();
draw_score();
gotoxy(LXPOS, LYPOS + 1);
clreol();
}
bool play_one_game(void)
{
byte item;
int nx, ny;
byte code;
gotoxy(LX2POS, LYPOS);
printf("Longest: %04d Highscore: %010ld\r", bestlength, bestscore);
gotoxy(LX2POS, LYPOS + 1);
printf("Best Time: %04d\r", besttid);
FOREVER
{
waitretrace();
delay(50);
millifemtio++;
if(!(millifemtio % 20))
{
millifemtio = 0;
tid++;
gotoxy(LXPOS, LYPOS + 1);
printf("Time: %04d\r", tid);
if(tid > besttid)
{
besttid = tid;
gotoxy(LX2POS, LYPOS + 1);
printf("Best Time: %04d\r", besttid);
}
}
if(keyhit())
{
code = getch();
if(code == 0)
{
code = getch();
switch(code)
{
case KEY_UP :
case KEY_DOWN :
case KEY_LEFT :
case KEY_RIGHT : key = code; break;
}
}
else
switch(toupper(code))
{
case KEY_ESC : return TRUE;
case KEY_SOUND : ljud = 1 - ljud;
setborderc(ljud * 12);
break;
}
}
nx = snx[head];
ny = sny[head];
switch(key)
{
case KEY_UP : ny -= 1; break;
case KEY_DOWN : ny += 1; break;
case KEY_LEFT : nx -= 1; break;
case KEY_RIGHT : nx += 1; break;
}
item = grid[nx][ny];
switch(item)
{
case HI(Block) : return FALSE;
case HI(Frog) : grow += 2 + random(ADDSNAKE);
score += GP * (length + grow) * (1 + (tid * tid) / 300);
replace_frog(nx, ny);
if(ljud)
{
buzz(250); delay(10); buzz(500); delay(10); quiet();
}
case HI(Clear) : head = (head + 1) % 1500;
snx[head] = nx;
sny[head] = ny;
set_point(nx, ny, Snake);
if(decline)
{
decline--;
length--;
if(length < 1)
return FALSE;
draw_score();
if(ljud)
{
buzz(1500); delay(5); quiet();
}
set_point(snx[tail], sny[tail], Clear);
tail = (tail + 1) % 1500;
}
if(grow)
{
grow--;
length++;
draw_score();
}
else
{
set_point(snx[tail], sny[tail], Clear);
tail = (tail + 1) % 1500;
}
break;
case HI(Brick) : decline += 1 + random(LOOSESNAKE);
set_point(nx, ny, Clear);
break;
case HI(Snake) : return FALSE;
}
check_frogs();
}
}
void play_game(void)
{
FOREVER
{
setup_game();
if(play_one_game())
return;
notify();
}
}
void set_up(void)
{
randomize();
textmode(C4350);
clrscr();
}
void clean_up(void)
{
textmode(C80);
printf("the Snake (c)1996 Fredrik Wangel (WaF)\r\n");
flushkbd();
}
int main(void)
{
save_palette();
fade_to_black();
set_up();
setborderc(12);
play_game();
setborderc(0);
fade_to_black();
hide_display();
clean_up();
clear_palette();
show_display();
fade_to_color();
restore_palette();
return 0;
}